import axios, {AxiosError, AxiosRequestConfig} from "axios";
import {Alert, ToastAndroid} from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import {AuthApi} from "../api/auth.ts";
import {getUserInfo, saveAccessToken, saveRefreshToken, saveUserInfo} from "./store.ts";
import {useAuthStore} from "../store/authStore.ts";

interface ApiResponse<T = any> {
    code: number;
    data: T;
    msg?: string;
}

let refreshTokenPromise: Promise<string> | null = null;

const instance = axios.create({
    baseURL: "http://gxuoabe.nnruibo.cn/app-api",
    // baseURL: "http://192.168.10.106:8080/app-api",
    withCredentials: true,
});

const AuthFail = () => {
    ToastAndroid.show("登录已过期，请重新登录", ToastAndroid.SHORT);
    useAuthStore.getState().clearAuth();
}

instance.interceptors.request.use(
    async (config: any) => {
        console.log(`[Request] --> ${config.method?.toUpperCase()} ${config.baseURL}${config.url}`, {
            params: config.params,
            data: config.data
        });
        const {accessToken: token} = useAuthStore.getState(); // 从 Zustand 获取 token
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    (error: any) => {
        return Promise.reject(error);
    }
);

// 响应拦截器
instance.interceptors.response.use(
    async (response: any) => {
        const config = response.config;
        console.log(`[Response] <-- ${config.method?.toUpperCase()} ${config.url}`, {
            status: response.status,
            data: response.data
        });
        const res = response.data;
        const originalRequest = response.config as AxiosRequestConfig & { _retry?: boolean };
        if (res.msg === "账号未登录") {
            console.log("账号未登录")
            originalRequest._retry = true;

            if (!refreshTokenPromise) {
                refreshTokenPromise = (async () => {
                    try {
                        const {refreshToken: currentRefreshToken} = useAuthStore.getState();

                        if (!currentRefreshToken) throw new Error("刷新令牌不存在");
                        try {
                            const refreshRes = await AuthApi.refreshToken(currentRefreshToken);

                            if (refreshRes.msg === "刷新令牌已过期") {
                                console.log("refreshRes", refreshRes)
                                const {userInfo} = useAuthStore.getState();
                                if (!userInfo || !userInfo.username || !userInfo.password) {
                                    AuthFail();
                                    throw new Error("无法自动重登录：用户信息或密码丢失");
                                }
                                const {username, password} = userInfo;
                                const loginRes = await AuthApi.login({username, password});
                                if (loginRes.code === 0 && loginRes.data.accessToken) {
                                    const {setAccessToken, setRefreshToken, setUserInfo} = useAuthStore.getState();
                                    const {userId, expiresTime, accessToken, refreshToken} = loginRes.data;

                                    const newUserInfo = {
                                        userid: userId.toString(),
                                        username: username,
                                        password: password,
                                        token: accessToken,
                                        refreshToken,
                                        expiresTime,
                                        localStorageTime: Date.now(),
                                        nickname: userInfo.nickname || '',
                                        deptNamesStr: userInfo.deptNamesStr || '',
                                    };

                                    setAccessToken(accessToken);
                                    setRefreshToken(refreshToken);
                                    setUserInfo(newUserInfo);

                                    console.log('Token re-stored successfully via password login!');
                                } else {
                                    console.error('Auto re-login failed with response:', loginRes);
                                    AuthFail(); // 自动登录失败，直接登出
                                    throw new Error('自动登录失败');
                                }
                            } else {
                                const {setAccessToken, setRefreshToken} = useAuthStore.getState();
                                const {accessToken, refreshToken} = refreshRes.data;

                                setAccessToken(accessToken);
                                setRefreshToken(refreshToken);

                                return accessToken;
                            }
                        } catch (e) {
                            console.log(e)
                        }
                    } catch (e) {
                        AuthFail();
                        throw new Error("刷新令牌失败");
                    } finally {
                        refreshTokenPromise = null;
                    }
                })();
            }

            try {
                const newAccessToken = await refreshTokenPromise;
                if (originalRequest.headers) {
                    originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
                }
                return instance(originalRequest);
            } catch (e) {
                return Promise.reject(e);
            }
        }

        return res;
    },
    async (error: AxiosError<ApiResponse>) => {
        if (error.response) {
            const config = error.response.config;
            console.error(`[Response Error] <-- ${config.method?.toUpperCase()} ${config.url}`, {
                status: error.response.status,
                data: error.response.data
            });
        }
        ToastAndroid.show(error.response?.data?.msg || "请求失败", ToastAndroid.SHORT);
        return Promise.reject(error);
    }
);

export const http = {
    get: <T = any>(url: string, params?: object): Promise<ApiResponse<T>> => {
        return instance.get(url, {params});
    },

    post: <T = any>(url: string, params?: object): Promise<ApiResponse<T>> => {
        return instance.post(url, params);
    },

    delete: <T = any>(url: string, params?: object): Promise<ApiResponse<T>> => {
        return instance.delete(url, params);
    },

    put: <T = any>(url: string, params?: object): Promise<ApiResponse<T>> => {
        return instance.put(url, params);
    }

};

export function urlWithParams(url: string, params: Record<string, any> = {}): string {
    Object.keys(params).forEach(key => {
        if (params[key] === undefined) {
            delete params[key];
        }
    });
    return (
        url +
        "?" +
        Object.keys(params)
            .map(key => key + "=" + encodeURIComponent(params[key]))
            .join("&")
    );
}
